using System;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityEditor.Rendering.HighDefinition;
using UnityEditor;

public class BloomSeparated : CustomPass
{
    [System.Serializable]
    public class BloomSettings
    {
        // [Range(0, 8)] public int downSampleLevels = 5;

        [Range(0, 3)] public float intensity = 1.0f;

        [Range(0, 16)] public float blurRadius = 1.0f;

        [Range(0, 2)] public float threshold = 0.7f;
    }

    public enum BloomMode
    {
        HDRP, //默认HDRP源码算法的Bloom
        StarRail //星铁算法的Bloom
    }

    [Header("Bloom模式选择")] public BloomMode bloomMode = BloomMode.StarRail;
    [Header("hdrp——角色Bloom设置")] public BloomSettings hd_characterBloom = new BloomSettings();
    [Header("hdrp——场景Bloom设置")] public BloomSettings hd_sceneBloom = new BloomSettings();
    [Header("星铁——角色Bloom设置")] public BloomSettings characterBloom = new BloomSettings();
    [Header("星铁——场景Bloom设置")] public BloomSettings sceneBloom = new BloomSettings();


    [Range(0, 8)] public int downSampleLevels = 5;
    //
    // [Range(0, 3)] public float intensity = 1.0f;
    //
    // [Range(0, 16)] public float blurRadius = 1.0f;
    //
    // [Range(0, 2)] public float threshold = 0.7f;

    Material downSampleMaterial;
    Material upSampleMaterial;
    Material blitCopyMaterial;
    Material thresholdExtractMaterial;


    //
    // RTHandle[] downSampleBuffers;
    // RTHandle[] hoSampleBuffer;
    // private RTHandle[] verSampleBuffer;
    // RTHandle thresholdBuffer;

    // 为角色和场景分别创建缓冲区
    RTHandle[] characterDownSampleBuffers;
    RTHandle[] characterHoSampleBuffer;
    RTHandle[] characterVerSampleBuffer;
    RTHandle characterThresholdBuffer;
    
    
    RTHandle[] sceneDownSampleBuffers;
    RTHandle[] sceneHoSampleBuffer;
    RTHandle[] sceneVerSampleBuffer;
    RTHandle sceneThresholdBuffer;


    private BloomSettings CurrentCharacterBloom
    {
        get { return bloomMode == BloomMode.HDRP ? hd_characterBloom : characterBloom; }
    }

    private BloomSettings CurrentSceneBloom
    {
        get { return bloomMode == BloomMode.HDRP ? hd_sceneBloom : sceneBloom; }
    }

    // 确保在Scene视图中也执行
    protected override bool executeInSceneView => true;

    // Trick to always include these shaders in build
    [SerializeField, HideInInspector] Shader downSampleShader;
    [SerializeField, HideInInspector] Shader upSampleShader;
    [SerializeField, HideInInspector] Shader blitCopyShader;
    [SerializeField, HideInInspector] Shader thresholdExtractShader;


    static class ShaderID
    {
        public static readonly int _Source = Shader.PropertyToID("_Source");
        public static readonly int _Source1 = Shader.PropertyToID("_Source1");
        public static readonly int _Source2 = Shader.PropertyToID("_Source2");
        public static readonly int _Source3 = Shader.PropertyToID("_Source3");
        public static readonly int _Source4 = Shader.PropertyToID("_Source4");

        //====场景==========
        public static readonly int _SceneSource1 = Shader.PropertyToID("_SceneSource1");
        public static readonly int _SceneSource2 = Shader.PropertyToID("_SceneSource2");
        public static readonly int _SceneSource3 = Shader.PropertyToID("_SceneSource3");
        public static readonly int _SceneSource4 = Shader.PropertyToID("_SceneSource4");
        //====场景==========


        public static readonly int _Intensity = Shader.PropertyToID("_Intensity");
        public static readonly int _Offset = Shader.PropertyToID("_Offset");
        public static readonly int _ViewPortSize = Shader.PropertyToID("_ViewPortSize");
        public static readonly int _Size = Shader.PropertyToID("_Size");
        public static readonly int _UpSize = Shader.PropertyToID("_UpSize");
        public static readonly int _Threshold = Shader.PropertyToID("_Threshold");
        public static readonly int _BufferCount = Shader.PropertyToID("_BufferCount");
        public static readonly int _SceneViewMode = Shader.PropertyToID("_SceneViewMode");

        public static readonly int _CharacterMaskTex = Shader.PropertyToID("_CharacterMaskTex");
        public static readonly int _IsCharacterBloom = Shader.PropertyToID("_IsCharacterBloom");
    }

    protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
    {
        if (downSampleShader == null)
            downSampleShader = Shader.Find("Hidden/Fullscreen/DownSample");
        if (upSampleShader == null)
            upSampleShader = Shader.Find("Hidden/Fullscreen/UpSampleSeparated");
        if (blitCopyShader == null)
            blitCopyShader = Shader.Find("Hidden/Fullscreen/BlitCopy");
        if (thresholdExtractShader == null)
            thresholdExtractShader = Shader.Find("Hidden/Fullscreen/ThresholdExtractSeparated");


        if (downSampleShader != null)
            downSampleMaterial = CoreUtils.CreateEngineMaterial(downSampleShader);
        if (upSampleShader != null)
            upSampleMaterial = CoreUtils.CreateEngineMaterial(upSampleShader);
        if (blitCopyShader != null)
            blitCopyMaterial = CoreUtils.CreateEngineMaterial(blitCopyShader);
        if (thresholdExtractShader != null)
            thresholdExtractMaterial = CoreUtils.CreateEngineMaterial(thresholdExtractShader);


        // 创建阈值提取缓冲区
        characterThresholdBuffer = RTHandles.Alloc(
            Vector2.one * 0.5f, TextureXR.slices, dimension: TextureXR.dimension,
            colorFormat: GraphicsFormat.B10G11R11_UFloatPack32,
            useDynamicScale: true, name: "characterThresholdBuffer"
        );
        sceneThresholdBuffer = RTHandles.Alloc(
            Vector2.one * 0.5f, TextureXR.slices, dimension: TextureXR.dimension,
            colorFormat: GraphicsFormat.B10G11R11_UFloatPack32,
            useDynamicScale: true, name: "sceneThresholdBuffer"
        );

        // int sampleLevels = Math.Max(characterBloom.downSampleLevels, sceneBloom.downSampleLevels);
        int sampleLevels = downSampleLevels;
        // 创建降采样和升采样缓冲区,这里可以用最大的
        characterDownSampleBuffers = new RTHandle[sampleLevels];
        characterHoSampleBuffer = new RTHandle[sampleLevels];
        characterVerSampleBuffer = new RTHandle[sampleLevels];

        sceneDownSampleBuffers = new RTHandle[sampleLevels];
        sceneHoSampleBuffer = new RTHandle[sampleLevels];
        sceneVerSampleBuffer = new RTHandle[sampleLevels];

        for (int i = 0; i < sampleLevels; i++)
        {
            float scale = 1.0f / Mathf.Pow(2, i + 2); //前面取阈值已经缩小过了，这里多缩小一倍

            characterDownSampleBuffers[i] = RTHandles.Alloc(
                Vector2.one * scale, TextureXR.slices, dimension: TextureXR.dimension,
                colorFormat: GraphicsFormat.B10G11R11_UFloatPack32,
                useDynamicScale: true, name: $"DownSampleBuffer_{i}"
            );

            characterHoSampleBuffer[i] = RTHandles.Alloc(
                Vector2.one * scale, TextureXR.slices, dimension: TextureXR.dimension,
                colorFormat: GraphicsFormat.B10G11R11_UFloatPack32,
                useDynamicScale: true, name: $"UpSampleBuffer_{i}"
            );

            characterVerSampleBuffer[i] = RTHandles.Alloc(
                Vector2.one * scale, TextureXR.slices, dimension: TextureXR.dimension,
                colorFormat: GraphicsFormat.B10G11R11_UFloatPack32,
                useDynamicScale: true, name: $"VerSampleBuffer_{i}"
            );

            sceneDownSampleBuffers[i] = RTHandles.Alloc(
                Vector2.one * scale, TextureXR.slices, dimension: TextureXR.dimension,
                colorFormat: GraphicsFormat.B10G11R11_UFloatPack32,
                useDynamicScale: true, name: $"DownSampleBuffer_{i}"
            );

            sceneHoSampleBuffer[i] = RTHandles.Alloc(
                Vector2.one * scale, TextureXR.slices, dimension: TextureXR.dimension,
                colorFormat: GraphicsFormat.B10G11R11_UFloatPack32,
                useDynamicScale: true, name: $"UpSampleBuffer_{i}"
            );

            sceneVerSampleBuffer[i] = RTHandles.Alloc(
                Vector2.one * scale, TextureXR.slices, dimension: TextureXR.dimension,
                colorFormat: GraphicsFormat.B10G11R11_UFloatPack32,
                useDynamicScale: true, name: $"VerSampleBuffer_{i}"
            );
        }
    }

    protected override void Execute(CustomPassContext ctx)
    {
        if (downSampleMaterial == null || upSampleMaterial == null || blitCopyMaterial == null ||
            thresholdExtractMaterial == null)
            return;

        // 只在主相机或场景视图中渲染
        if (ctx.hdCamera.camera != Camera.main && ctx.hdCamera.camera.cameraType != CameraType.SceneView)
            return;

        RTHandle source = (targetColorBuffer == TargetBuffer.Camera)
            ? ctx.cameraColorBuffer
            : ctx.customColorBuffer.Value;

        // 检测是否为Scene视图
        bool isSceneView = ctx.hdCamera.camera.cameraType == CameraType.SceneView;

        // 第一步：分别提取角色和场景的阈值
        PerformThresholdExtract(ctx, source, isSceneView);

        // 第二步：分别对角色和场景进行降采样
        PerformDownSample(ctx, isSceneView, true); // 角色
        PerformDownSample(ctx, isSceneView, false); // 场景

        // 第三步：分别对角色和场景进行上采样
        PerformUpSample(ctx, isSceneView, true); // 角色
        PerformUpSample(ctx, isSceneView, false); // 场景

        // 第四步：合成到最终目标
        Compsite(ctx, source, isSceneView);
        // // 第一步：阈值提取
        // PerformThresholdExtract(ctx, source, isSceneView);
        //
        // // 降采样过程
        // PerformDownSample(ctx, thresholdBuffer, isSceneView);
        //
        // // 升采样过程（Bloom效果）
        // PerformUpSample(ctx, source, isSceneView);
        //
        // Compsite(ctx, source, isSceneView);
    }


    // void PerformThresholdExtract(CustomPassContext ctx, RTHandle source, bool isSceneView)
    // {
    //     float threshold = characterBloom.threshold;
    //     var properties = new MaterialPropertyBlock();
    //     properties.SetTexture(ShaderID._Source, source);
    //     properties.SetFloat(ShaderID._Threshold, threshold);
    //     properties.SetFloat(ShaderID._Intensity, 1.0f);
    //     properties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);
    //
    //     HDUtils.DrawFullScreen(ctx.cmd, thresholdExtractMaterial, thresholdBuffer, properties, shaderPassId: 0);
    // }
    //
    //
    // void PerformDownSample(CustomPassContext ctx, RTHandle source, bool isSceneView)
    // {
    //     RTHandle currentSource = source;
    //     for (int i = 0; i < downSampleLevels; i++)
    //     {
    //         var targetBuffer = downSampleBuffers[i];
    //
    //
    //         // 后续降采样：使用自定义降采样shader
    //         Vector2Int sourceSize =
    //             currentSource.GetScaledSize(currentSource.rtHandleProperties.currentViewportSize);
    //
    //         var properties = new MaterialPropertyBlock();
    //         properties.SetTexture(ShaderID._Source, currentSource);
    //         properties.SetVector(ShaderID._Offset, new Vector4(1.0f / sourceSize.x, 1.0f / sourceSize.y, 0, 0));
    //         properties.SetVector(ShaderID._Size, new Vector4(i, i, 0, 0));
    //         properties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);
    //
    //         HDUtils.DrawFullScreen(ctx.cmd, downSampleMaterial, targetBuffer, properties, shaderPassId: 0);
    //
    //         currentSource = targetBuffer;
    //     }
    // }
    //
    // void PerformUpSample(CustomPassContext ctx, RTHandle finalTarget, bool isSceneView)
    // {
    //     // 从最小的mip级别开始向上采样
    //     RTHandle currentSource = downSampleBuffers[1];
    //     
    //     float intensity = characterBloom.intensity;
    //     float blurRadius = characterBloom.blurRadius;
    //     
    //     for (int i = 1; i < downSampleLevels; i++)
    //     {
    //         currentSource = downSampleBuffers[i];
    //         RTHandle targetBuffer = hoSampleBuffer[i];
    //         Vector2Int scaledSize = targetBuffer.GetScaledSize(targetBuffer.rtHandleProperties.currentViewportSize);
    //
    //         // 使用MaterialPropertyBlock设置升采样参数
    //         var properties = new MaterialPropertyBlock();
    //         properties.SetTexture(ShaderID._Source, currentSource);
    //         properties.SetFloat(ShaderID._Intensity, intensity);
    //         properties.SetVector(ShaderID._Offset,
    //             new Vector4(blurRadius / scaledSize.x, blurRadius / scaledSize.y, 0, 0));
    //         properties.SetVector(ShaderID._UpSize, new Vector4(i, i, 0, 0));
    //         properties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);
    //
    //         HDUtils.DrawFullScreen(ctx.cmd, upSampleMaterial, targetBuffer, properties, shaderPassId: 0);
    //
    //         currentSource = targetBuffer;
    //     }
    //
    //     for (int i = 1; i < downSampleLevels; i++)
    //     {
    //         currentSource = hoSampleBuffer[i];
    //         RTHandle targetBuffer = verSampleBuffer[i];
    //         Vector2Int scaledSize = targetBuffer.GetScaledSize(targetBuffer.rtHandleProperties.currentViewportSize);
    //
    //         // 使用MaterialPropertyBlock设置升采样参数
    //         var properties = new MaterialPropertyBlock();
    //         properties.SetTexture(ShaderID._Source, currentSource);
    //         properties.SetFloat(ShaderID._Intensity, intensity);
    //         properties.SetVector(ShaderID._Offset,
    //             new Vector4(blurRadius / scaledSize.x, blurRadius / scaledSize.y, 0, 0));
    //         properties.SetVector(ShaderID._UpSize, new Vector4(i, i, 0, 0));
    //         properties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);
    //
    //         HDUtils.DrawFullScreen(ctx.cmd, upSampleMaterial, targetBuffer, properties, shaderPassId: 1);
    //     }
    // }
    //
    // void Compsite(CustomPassContext ctx, RTHandle finalTarget, bool isSceneView)
    // {
    //     
    //     float intensity = characterBloom.intensity;
    //     
    //     // 最终合成到目标缓冲区
    //     if (verSampleBuffer.Length > 1)
    //     {
    //         var properties = new MaterialPropertyBlock();
    //
    //         // 传递多个verSampleBuffer纹理给shader
    //         if (verSampleBuffer[1] != null)
    //             properties.SetTexture(ShaderID._Source1, verSampleBuffer[1]);
    //         if (verSampleBuffer.Length > 2 && verSampleBuffer[2] != null)
    //             properties.SetTexture(ShaderID._Source2, verSampleBuffer[2]);
    //         if (verSampleBuffer.Length > 3 && verSampleBuffer[3] != null)
    //             properties.SetTexture(ShaderID._Source3, verSampleBuffer[3]);
    //         if (verSampleBuffer.Length > 4 && verSampleBuffer[4] != null)
    //             properties.SetTexture(ShaderID._Source4, verSampleBuffer[4]);
    //
    //         properties.SetFloat(ShaderID._Intensity, intensity);
    //         properties.SetInt(ShaderID._BufferCount, Mathf.Min(verSampleBuffer.Length - 1, 4)); // 传递有效缓冲区数量
    //         properties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);
    //
    //         HDUtils.DrawFullScreen(ctx.cmd, upSampleMaterial, finalTarget, properties, shaderPassId: 2);
    //     }
    // }

    // protected override void Cleanup()
    // {
    //     CoreUtils.Destroy(downSampleMaterial);
    //     CoreUtils.Destroy(upSampleMaterial);
    //     CoreUtils.Destroy(blitCopyMaterial);
    //     CoreUtils.Destroy(thresholdExtractMaterial);
    //
    //     thresholdBuffer?.Release();
    //
    //     if (downSampleBuffers != null)
    //     {
    //         for (int i = 0; i < downSampleBuffers.Length; i++)
    //         {
    //             downSampleBuffers[i]?.Release();
    //         }
    //     }
    //
    //     if (hoSampleBuffer != null)
    //     {
    //         for (int i = 0; i < hoSampleBuffer.Length; i++)
    //         {
    //             hoSampleBuffer[i]?.Release();
    //         }
    //     }
    //
    //     if (verSampleBuffer != null)
    //     {
    //         for (int i = 0; i < verSampleBuffer.Length; i++)
    //         {
    //             verSampleBuffer[i]?.Release();
    //         }
    //     }
    // }
    void PerformThresholdExtract(CustomPassContext ctx, RTHandle source, bool isSceneView)
    {
        // 提取角色阈值（使用角色参数）
        var characterProperties = new MaterialPropertyBlock();
        characterProperties.SetTexture(ShaderID._Source, source);
        characterProperties.SetFloat(ShaderID._Threshold, CurrentCharacterBloom.threshold);
        characterProperties.SetFloat(ShaderID._Intensity, 1.0f);
        characterProperties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);
        characterProperties.SetFloat(ShaderID._IsCharacterBloom, 1.0f); // 标记为角色Bloom

        HDUtils.DrawFullScreen(ctx.cmd, thresholdExtractMaterial, characterThresholdBuffer, characterProperties,
            shaderPassId: 0);

        // 提取场景阈值（使用场景参数）
        var sceneProperties = new MaterialPropertyBlock();
        sceneProperties.SetTexture(ShaderID._Source, source);
        sceneProperties.SetFloat(ShaderID._Threshold, CurrentSceneBloom.threshold);
        sceneProperties.SetFloat(ShaderID._Intensity, 1.0f);
        sceneProperties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);
        sceneProperties.SetFloat(ShaderID._IsCharacterBloom, 0.0f); // 标记为场景Bloom

        HDUtils.DrawFullScreen(ctx.cmd, thresholdExtractMaterial, sceneThresholdBuffer, sceneProperties,
            shaderPassId: 0);
    }

    void PerformDownSample(CustomPassContext ctx, bool isSceneView, bool isCharacter)
    {
        RTHandle[] downSampleBuffers = isCharacter ? characterDownSampleBuffers : sceneDownSampleBuffers;
        RTHandle thresholdBuffer = isCharacter ? characterThresholdBuffer : sceneThresholdBuffer;

        RTHandle currentSource = thresholdBuffer;

        for (int i = 0; i < downSampleLevels; i++)
        {
            var targetBuffer = downSampleBuffers[i];
            Vector2Int sourceSize = currentSource.GetScaledSize(currentSource.rtHandleProperties.currentViewportSize);

            var properties = new MaterialPropertyBlock();
            properties.SetTexture(ShaderID._Source, currentSource);
            properties.SetVector(ShaderID._Offset, new Vector4(1.0f / sourceSize.x, 1.0f / sourceSize.y, 0, 0));
            properties.SetVector(ShaderID._Size, new Vector4(i, i, 0, 0));
            properties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);
            properties.SetFloat(ShaderID._IsCharacterBloom, isCharacter ? 1.0f : 0.0f);

            HDUtils.DrawFullScreen(ctx.cmd, downSampleMaterial, targetBuffer, properties, shaderPassId: 0);

            currentSource = targetBuffer;
        }
    }

    void PerformUpSample(CustomPassContext ctx, bool isSceneView, bool isCharacter)
    {
        RTHandle[] downSampleBuffers = isCharacter ? characterDownSampleBuffers : sceneDownSampleBuffers;
        RTHandle[] hoSampleBuffer = isCharacter ? characterHoSampleBuffer : sceneHoSampleBuffer;
        RTHandle[] verSampleBuffer = isCharacter ? characterVerSampleBuffer : sceneVerSampleBuffer;

        BloomSettings settings = isCharacter ? CurrentCharacterBloom : CurrentSceneBloom;
        float intensity = settings.intensity;
        float blurRadius = settings.blurRadius;

        // 水平模糊
        for (int i = 1; i < downSampleLevels; i++)
        {
            RTHandle currentSource = downSampleBuffers[i];
            RTHandle targetBuffer = hoSampleBuffer[i];
            Vector2Int scaledSize = targetBuffer.GetScaledSize(targetBuffer.rtHandleProperties.currentViewportSize);

            var properties = new MaterialPropertyBlock();
            properties.SetTexture(ShaderID._Source, currentSource);
            properties.SetFloat(ShaderID._Intensity, intensity);
            properties.SetVector(ShaderID._Offset,
                new Vector4(blurRadius / scaledSize.x, blurRadius / scaledSize.y, 0, 0));
            properties.SetVector(ShaderID._UpSize, new Vector4(i, i, 0, 0));
            properties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);
            properties.SetFloat(ShaderID._IsCharacterBloom, isCharacter ? 1.0f : 0.0f);

            HDUtils.DrawFullScreen(ctx.cmd, upSampleMaterial, targetBuffer, properties, shaderPassId: 0);
        }

        // 垂直模糊
        for (int i = 1; i < downSampleLevels; i++)
        {
            RTHandle currentSource = hoSampleBuffer[i];
            RTHandle targetBuffer = verSampleBuffer[i];
            Vector2Int scaledSize = targetBuffer.GetScaledSize(targetBuffer.rtHandleProperties.currentViewportSize);

            var properties = new MaterialPropertyBlock();
            properties.SetTexture(ShaderID._Source, currentSource);
            properties.SetFloat(ShaderID._Intensity, intensity);
            properties.SetVector(ShaderID._Offset,
                new Vector4(blurRadius / scaledSize.x, blurRadius / scaledSize.y, 0, 0));
            properties.SetVector(ShaderID._UpSize, new Vector4(i, i, 0, 0));
            properties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);
            properties.SetFloat(ShaderID._IsCharacterBloom, isCharacter ? 1.0f : 0.0f);

            HDUtils.DrawFullScreen(ctx.cmd, upSampleMaterial, targetBuffer, properties, shaderPassId: 1);
        }
    }

    void Compsite(CustomPassContext ctx, RTHandle finalTarget, bool isSceneView)
    {
        var properties = new MaterialPropertyBlock();

        // 传递角色Bloom缓冲区
        if (characterVerSampleBuffer.Length > 1 && characterVerSampleBuffer[1] != null)
            properties.SetTexture(ShaderID._Source1, characterVerSampleBuffer[1]);
        if (characterVerSampleBuffer.Length > 2 && characterVerSampleBuffer[2] != null)
            properties.SetTexture(ShaderID._Source2, characterVerSampleBuffer[2]);
        if (characterVerSampleBuffer.Length > 3 && characterVerSampleBuffer[3] != null)
            properties.SetTexture(ShaderID._Source3, characterVerSampleBuffer[3]);
        if (characterVerSampleBuffer.Length > 4 && characterVerSampleBuffer[4] != null)
            properties.SetTexture(ShaderID._Source4, characterVerSampleBuffer[4]);

        // 传递场景Bloom缓冲区 - 需要添加新的ShaderID
        if (sceneVerSampleBuffer.Length > 1 && sceneVerSampleBuffer[1] != null)
            properties.SetTexture(ShaderID._SceneSource1, sceneVerSampleBuffer[1]);
        if (sceneVerSampleBuffer.Length > 2 && sceneVerSampleBuffer[2] != null)
            properties.SetTexture(ShaderID._SceneSource2, sceneVerSampleBuffer[2]);
        if (sceneVerSampleBuffer.Length > 3 && sceneVerSampleBuffer[3] != null)
            properties.SetTexture(ShaderID._SceneSource3, sceneVerSampleBuffer[3]);
        if (sceneVerSampleBuffer.Length > 4 && sceneVerSampleBuffer[4] != null)
            properties.SetTexture(ShaderID._SceneSource4, sceneVerSampleBuffer[4]);

        // 传递场景Bloom缓冲区（使用不同的ShaderID或通过数组索引）
        // properties.SetFloat(ShaderID._Intensity, 1.0f); // 强度在Shader中分别控制
        // properties.SetInt(ShaderID._BufferCount, Mathf.Min(characterVerSampleBuffer.Length - 1, 4));
        // properties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);

        // 设置各自的强度
        properties.SetFloat("_CharacterIntensity", CurrentCharacterBloom.intensity);
        properties.SetFloat("_SceneIntensity", CurrentSceneBloom.intensity);

        properties.SetInt(ShaderID._BufferCount, Mathf.Min(characterVerSampleBuffer.Length - 1, 4));
        properties.SetFloat(ShaderID._SceneViewMode, isSceneView ? 1.0f : 0.0f);


        HDUtils.DrawFullScreen(ctx.cmd, upSampleMaterial, finalTarget, properties, shaderPassId: 2);
    }

    protected override void Cleanup()
    {
        CoreUtils.Destroy(downSampleMaterial);
        CoreUtils.Destroy(upSampleMaterial);
        CoreUtils.Destroy(blitCopyMaterial);
        CoreUtils.Destroy(thresholdExtractMaterial);

        characterThresholdBuffer?.Release();
        sceneThresholdBuffer?.Release();

        ReleaseBufferArray(characterDownSampleBuffers);
        ReleaseBufferArray(sceneDownSampleBuffers);
        ReleaseBufferArray(characterHoSampleBuffer);
        ReleaseBufferArray(sceneHoSampleBuffer);
        ReleaseBufferArray(characterVerSampleBuffer);
        ReleaseBufferArray(sceneVerSampleBuffer);
    }

    void ReleaseBufferArray(RTHandle[] buffers)
    {
        if (buffers != null)
        {
            for (int i = 0; i < buffers.Length; i++)
            {
                buffers[i]?.Release();
            }
        }
    }
}